%define	VIDEOMEM	0xB800

; Main interrupt handler (int 30h)
int30h_handler:

	push	int30h_end

	; AH = function number
	cmp	ah,	0h
	je	i30_0			; function 0 - clear screen
	dec	ah
	jz	i30_1			; function 1 - print string
	dec	ah
	jz	i30_2			; function 2 - print char
	dec	ah
	jz	i30_3			; function 3 - print number
	dec	ah
	jz	i30_4

	ret

; AH=0: clear screen (set video mode to 3)

	i30_0:
		mov	ax,	0003h	; ah=0, al=3
		int	10h		; set video mode to 3
		mov	eax,	0h	; operation successfull
		ret			; done

; AH=1: prints string to STDOUT
;	SI - string buffer

;	xor	eax,	eax
;	mov	ax,	ds
;	add	esi,	eax

	i30_1:
		push	edx
		push	ebx
		push	eax
		mov	ah,	0xE
		xor	bh,	bh
		mov	bl,	0x7
		mov	edx,	esi
	.next:
		mov	al,	[edx]
		or	al,	al
		jz	.return
		inc	edx
		int	10h
		jmp	.next

	.return:
		pop	eax
		pop	ebx
		pop	edx
	ret

	i30_1_old:
		push	ebx		; save EBX
		push	eax		; save EAX
		mov	ah,	0xE
		xor	bh,	bh
		mov	bl,	0x7
	.next:
		lodsb			; load next number
		or	al,	al
		jz	.return		; exit loop
		int	10h		; print char
		jmp	.next		; next char
	.return:
		pop	eax		; restore EAX
		pop	ebx		; restore EBX
;		mov	ax,	0h	; operation successfull
		ret			; done

; AH=2: prints symbol from AL
;	AL - symbol code

	i30_2:
		push	ebx		; save EBX

		mov	ah,	0Eh	; function 14
		mov	bh,	0	; page number
		int	10h		; print symbol

		pop	ebx		; restore EBX
		mov	eax,	0h	; operation successfull

		ret			; done


; AH=3: print number from DX to STDOUT
;	DX - number (WORD)

	i30_3:
;		int	18h

		push	ax
		push	bx
		push	cx
		push	dx		; save registers

		mov	ax,	dx	; number will now be in AX

		mov	bx,	10	; decimal system
		xor	dx,	dx	; dx = 0
		xor	cx,	cx	; cx = 0
	.next:
		xor	dx,	dx	; dx = 0
		div	bx		; dx:ax % bx -> dx
		add	dl,	30h	; convert to ASCII digit
		push	dx		; push into stack
		inc	cx		; increase digits count
		cmp	al,	0	; if source is still > 0, then
		jne	.next		; loop
	.print:
		pop	ax		; get digit from stack
		mov	ah,	2	; character code
		int	30h		; print char
		loop	.print		; loop
		pop	dx
		pop	cx
		pop	bx		; restore registers
		pop	ax
;		mov	eax,	0h	; operation successfull
		ret			; done

	i30_4:
		ret


; interrupt ends here
	int30h_end:
iret
